﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using Lenovo.CFI.BLL.DicMgr;
using Lenovo.CFI.BLL.Mail;
using Lenovo.CFI.Common;
using Lenovo.CFI.Common.Dic;
using Lenovo.CFI.Common.Mail;
using Lenovo.CFI.DAL;
using Lenovo.CFI.Common.Sys;
using Lenovo.CFI.DAL.Sys;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using System.IO;
using NPOI.HPSF;

namespace Lenovo.CFI.BLL
{
    public class IdeaBl
    {
        #region get -- owner

        public List<Idea> GetIdeaForOwner(string owner, int? topicID, string submitType, IdeaStatus? status,
            string finalNextAction, int? finalActionStatus)
        {
            return IdeaDa.GetIdea(topicID, null, owner, null, null, null, submitType, status, null, null,
                null, finalNextAction, null, finalActionStatus, null);
        }

        #endregion

        #region get -- approver

        public List<Idea> GetIdeaForApprover(string approver, int? topicID, IdeaStatus? status)
        {
            return IdeaDa.GetIdea(topicID, null, null, null, null, null, null, status, null, approver,
                null, null, null, null, null);
        }


        #endregion

        #region get -- manager and vp

        #endregion

        #region get -- dc owner

        public List<Idea> GetIdeaForDC(int topicID, List<string> types)
        {
            return IdeaDa.GetIdea(topicID, null, null, null, null, null, null, null, 
                new List<int>(), null, null, null, null, null, null).FindAll(
                i => types.Contains(i.Type) && (i.Status != IdeaStatus.Draft && i.Status != IdeaStatus.Reject));
        }


        #endregion

        #region get -- ip owner

        #endregion

        #region get -- executor

        #endregion


        public Idea GetIdeaById(int id)
        {
            return IdeaDa.GetByID(id);
        }

        public List<Idea> GetIdeaByIds(List<int> ids)
        {
            return IdeaDa.GetByIDs(ids);
        }

        public List<Idea> GetIdeaByReviews(List<IdeaReview> reviews)
        {
            List<int> ideaIDs = new List<int>();
            foreach (IdeaReview r in reviews) ideaIDs.Add(r.IdeaID);
            return IdeaDa.GetByIDs(ideaIDs);
        }


        public List<Idea> GetIdeaForReview(int topicID)
        {
            return IdeaDa.GetIdeaForReview(topicID);
        }

        public List<Idea> GetIdeaByScheduleTopic(int topicID)
        {
            return IdeaDa.GetIdeaByScheduleTopic(topicID);
        }

        public List<Idea> GetIdeaByScheduleTopicForAdd(int topicID)
        {
            return IdeaDa.GetIdeaByScheduleTopicForAdd(topicID);
        }


        #region search

        public List<Idea> SearchIdeaForStat(int? belongTopicID,
            DateTime? topicTimeF, DateTime? topicTimeT)
        {
            return IdeaDa.SearchIdea(belongTopicID,
                 null, null, null, null, null, null, null,
                 null, null, null, null, null, null, null,
                 new List<int>(new int[] { (int)IdeaStatus.Suggestion, (int)IdeaStatus.Execution, (int)IdeaStatus.Closed }), 
                 true, null, null,
                 topicTimeF, topicTimeT, 
                 null, null, null, null, null, null, null,
                 null);
        }


        public List<Idea> SearchIdea(int? belongTopicID,
            string title, string owner, int? ideaTeamID, int? ownerCurrentTeamID,
            string ideaTeamManager, string ownerCurrentManager, string ideaCurrentTeamManager,
            string ideaTeamVP, string ownerCurrentTeamVP, string ideaCurrentTeamVP,
            string submitType, List<string> relatedTypes, List<string> keyworkds,
            IdeaStatus? status, List<int> multiStatus, bool? searchable, DateTime? submitTimeF, DateTime? submitTimeT,
            DateTime? topicTimeF, DateTime? topicTimeT, string finalType, List<string> multiFinalTypes, string finalAction, bool? finalIP,
            int? finalActionStatus, int? finalIPStatus, int? finalAward,
            string user)
        {
            return IdeaDa.SearchIdea(belongTopicID,
               title, owner, ideaTeamID, ownerCurrentTeamID, 
               ideaTeamManager, ownerCurrentManager, ideaCurrentTeamManager, 
               ideaTeamVP, ownerCurrentTeamVP, ideaCurrentTeamVP,
               submitType, relatedTypes, keyworkds,
               status, multiStatus, searchable, submitTimeF, submitTimeT,
               topicTimeF, topicTimeT, finalType, multiFinalTypes, finalAction, finalIP,
               finalActionStatus, finalIPStatus, finalAward,
               user);
        }

        #endregion

        #region process

        public void Add(Idea idea, bool submit)
        {
            Topic topic = TopicDa.GetTopicByID(idea.TopicID);

            idea.SubmitTime = DateTime.Now;
            idea.SecretLevel = 1;
            idea.CanSearch = false;

            if (idea.SubmitTime < topic.StartTime || idea.SubmitTime > topic.DeadlineTime.Value)
            {
                throw new BusinessObjectLogicException("The topic does not start or has been stoped!");
            }


            User user = UserDa.GetUserByItCode(idea.Owner);
            idea.TeamID = user.TeamID;
            idea.TeamManager = user.Manager;
            idea.TeamVP = user.VP;

            if (submit)
            {
                if (idea.Approver == null)
                    idea.Status = IdeaStatus.Submitted;
                else
                    idea.Status = IdeaStatus.Approving;
            }
            else
                idea.Status = IdeaStatus.Draft;

            IdeaDa.InsertIdea(idea);


            if (idea.Status == IdeaStatus.Approving)
            {
                new MailBl().MailIdeaApproval(idea.ID, idea.Title, idea.Owner, MailBl.ConvertMailAddress(idea.Approver));
            }
        }

        public void Delete(int id)
        {
            Idea idea = IdeaDa.GetByID(id);
            if (idea == null) throw new BusinessObjectExistException("The specified idea does not exist!");
            if (idea.Status != IdeaStatus.Draft) throw new BusinessObjectExistException("The specified idea can't be deleted!");

            IdeaDa.DeleteIdea(id);
        }

        public void Update(int id, string title, string type, List<string> relatedTypes,
            List<string> keywords, string freewordsText, string backgroud, string description, string values,
            Guid? pptFileID, Guid? pic1FileID, Guid? pic2FileID, Guid? pic3FileID, string approver, bool submit)
        {
            Idea existIdea = IdeaDa.GetByID(id);
            if (existIdea == null) throw new BusinessObjectExistException("The specified idea does not exist!");
            if (existIdea.Status != IdeaStatus.Draft && 
                existIdea.Status != IdeaStatus.Submitted && 
                existIdea.Status != IdeaStatus.Approving) throw new BusinessObjectExistException("The specified idea can't be changed!");


            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {

                    string log = "Update at " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    IdeaDa.InsertIdeaHis(existIdea, log, trans);

                    existIdea.Title = title;
                    existIdea.Type = type;
                    existIdea.RelatedType = CodeList.CreateByList(relatedTypes.ToArray());
                    existIdea.Keywords = CodeList.CreateByList(keywords.ToArray());
                    existIdea.Freewords = new CodeList(freewordsText);
                    existIdea.Backgroud = backgroud;
                    existIdea.Description = description;
                    existIdea.Values = values;
                    existIdea.PptFileID = pptFileID;
                    existIdea.Pic1FileID = pic1FileID;
                    existIdea.Pic2FileID = pic2FileID;
                    existIdea.Pic3FileID = pic3FileID;
                    existIdea.Approver = approver;
                    existIdea.ApproverComment = null;

                    if (submit)
                    {
                        if (existIdea.Approver == null)
                            existIdea.Status = IdeaStatus.Submitted;
                        else
                            existIdea.Status = IdeaStatus.Approving;
                    }
                    else
                        existIdea.Status = IdeaStatus.Draft;

                    IdeaDa.UpdateIdea(existIdea, trans);
                    
                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }

        }

        public void Approve(int id, bool agree, string comment)
        {
            Idea idea = IdeaDa.GetByID(id);
            if (idea == null) throw new BusinessObjectExistException("The specified idea does not exist!");

            if (idea.Status != IdeaStatus.Approving) throw new BusinessObjectExistException("The specified idea can't be changed!");

            idea.Status = agree ? IdeaStatus.Agree : IdeaStatus.Reject;
            idea.ApproverComment = comment;

            IdeaDa.UpdateIdea(idea);

        }

        public void DcComment(int id, string opionion, bool meeting)
        {
            Idea idea = IdeaDa.GetByID(id);
            if (idea == null) throw new BusinessObjectExistException("The specified idea does not exist!");

            if (idea.Status != IdeaStatus.Submitted && 
                idea.Status != IdeaStatus.Agree) throw new BusinessObjectExistException("The specified idea can't be changed!");

            idea.DcComment = opionion;
            idea.DcAttendMeeting = meeting;

            IdeaDa.UpdateIdea(idea);
        }

        #endregion



        public static string ExportIdeaList(List<Idea> ideas, Dictionary<int, IdeaReview> reviewsDic)
        {
            Workbook workbook = NPOIHelper.CreateWorkbookFromTemplate(TemplatePath.ExcelTemplate() + "\\" + "IdeaList.xls");
            Sheet sheet = workbook.GetSheet("IdeaList");

            // 填充数据
            if (ideas!=null)
            {
                for (int i = 0; i < ideas.Count; i++)
                {
                    Idea idea = ideas[i];
                    Row row = sheet.CreateRow(i + 1);
                    row.CreateCell(0).SetCellValue(i + 1);
                    row.CreateCell(1).SetCellValue(idea.Title);
                    row.CreateCell(2).SetCellValue(idea.Owner);
                    row.CreateCell(3).SetCellValue(IdeaTypeDicMgr.GetByCode(idea.FinalType).Title);
                    row.CreateCell(4).SetCellValue(NextActionDicMgr.GetByCode(idea.FinalAction).Title);
                }
            }
            return NPOIHelper.SaveWorkbookToExcel(Path.GetTempPath(), Path.GetRandomFileName(), workbook);
        }
    
    }
}
